#include <odb/database.hxx>
#include <odb/mysql/database.hxx>
#include "student.hxx"
#include "student-odb.hxx"
#include <gflags/gflags.h>

DEFINE_string(host, "127.0.0.1", "这是MySQL服务器地址");
DEFINE_int32(port, 0, "这是MySQL服务器端口");
DEFINE_string(db, "TestDB", "数据库默认库名称");
DEFINE_string(user, "root", "数据库用户名");
DEFINE_string(passwd, "123456", "数据库密码");
DEFINE_string(charset, "utf8", "数据库字符集");
DEFINE_int32(max_pool_size, 3, "最大连接池数量");

void insert_classes(odb::mysql::database &db)
{
    Classes c1("一班");
    Classes c2("二班");
    try
    {
        odb::transaction t(db.begin());
        db.persist(c1);
        db.persist(c2);
        t.commit();
    }
    catch (const odb::exception &e)
    {
        std::cerr << "插入班级数据出错: " << e.what() << std::endl;
    }
}

void insert_student(odb::mysql::database &db)
{
    Student s1(1, "张三", 18, 1);
    Student s2(2, "李四", 19, 1);
    Student s3(3, "王五", 20, 1);
    Student s4(4, "赵六", 21, 2);
    Student s5(5, "钱七", 22, 2);
    Student s6(6, "孙八", 23, 2);
    try
    {
        odb::transaction t(db.begin());
        db.persist(s1);
        db.persist(s2);
        db.persist(s3);
        db.persist(s4);
        db.persist(s5);
        db.persist(s6);
        t.commit();
    }
    catch (const odb::exception &e)
    {
        std::cerr << "插入学生数据出错: " << e.what() << std::endl;
    }
}

void update_student(odb::mysql::database &db, Student &stu)
{
    try
    {
        odb::transaction t(db.begin());
        db.update(stu);
        t.commit();
    }
    catch (const odb::exception &e)
    {
        std::cerr << "更新学生数据出错: " << e.what() << std::endl;
    }
}

Student select_student(odb::mysql::database &db)
{
    Student res;
    try
    {
        odb::transaction t(db.begin());
        typedef odb::query<Student> query;
        odb::result<Student> result = db.query<Student>(query::name == "张三");
        if (result.size() != 1)
        {
            std::cout << "查询结果数量不等于1" << std::endl;
            return Student();
        }
        res = *result.begin();
        t.commit();
    }
    catch (const odb::exception &e)
    {
        std::cerr << "查询学生数据出错: " << e.what() << std::endl;
    }
    return res;
}

void reomve_student(odb::mysql::database &db)
{
    try
    {
        odb::transaction t(db.begin());
        typedef odb::query<Student> query;
        db.erase_query<Student>(query::class_id == 2);
        t.commit();
    }
    catch (const odb::exception &e)
    {
        std::cerr << "删除学生数据出错: " << e.what() << std::endl;
    }
}

void classes_student(odb::mysql::database &db)
{
    try
    {
        odb::transaction t(db.begin());
        typedef odb::query<struct Student_Classes> query;
        typedef odb::result<struct Student_Classes> result;
        result res = db.query<struct Student_Classes>(query::classes::id == 1);
        for (result::iterator it = res.begin(); it != res.end(); ++it)
        {
            std::cout << it->id << std::endl;
            std::cout << it->student_id << std::endl;
            std::cout << it->student_name << std::endl;
            std::cout << it->age << std::endl;
            std::cout << it->classes_name << std::endl;
        }
        t.commit();
    }
    catch (const odb::exception &e)
    {
        std::cout << "查询学生数据出错: " << e.what() << std::endl;
    }
}

void all_student(odb::mysql::database &db)
{
    try
    {
        odb::transaction t(db.begin());
        typedef odb::query<Student> query;
        typedef odb::result<struct all_student_name> result;
        result res = db.query<struct all_student_name>(query::class_id == 1);
        for (result::iterator it = res.begin(); it != res.end(); ++it)
        {
            std::cout << it->name << std::endl;
        }
        t.commit();
    }
    catch (const odb::exception &e)
    {
        std::cout << "查询学生姓名数据出错: " << e.what() << std::endl;
    }
}

int main(int argc, char *argv[])
{
    google::ParseCommandLineFlags(&argc, &argv, true);
    // 1.构造连接工厂配置对象
    std::unique_ptr<odb::mysql::connection_pool_factory> cpf(new odb::mysql::connection_pool_factory(FLAGS_max_pool_size, 0));
    // 2.构造数据库对象
    odb::mysql::database db(FLAGS_user, FLAGS_passwd, FLAGS_db, FLAGS_host, FLAGS_port, "", FLAGS_charset, 0, std::move(cpf));
    // 3.数据操作
    // insert_classes(db);
    // insert_student(db);

    // Student stu = select_student(db);
    // std::cout << "student_id: " << stu.get_student_id() << std::endl;
    // std::cout << "name: " << stu.get_name() << std::endl;
    // if (stu.get_age())
    // {
    //     std::cout << "age: " << stu.get_age() << std::endl;
    // }
    // std::cout << "class_id: " << stu.get_class_id() << std::endl;

    // stu.set_age(15);
    // update_student(db, stu);
    // reomve_student(db);
    all_student(db);
    return 0;
}
